/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package classe.controlador;

import classe.controlador.exceptions.IllegalOrphanException;
import classe.controlador.exceptions.NonexistentEntityException;
import java.io.Serializable;
import javax.persistence.Query;
import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import classe.entidade.Usuario;
import classe.entidade.Documento;
import classe.entidade.Estoque;
import classe.entidade.Movimento;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 *
 * @author Kellison
 */
public class MovimentoJpaController implements Serializable {

    public MovimentoJpaController(EntityManagerFactory emf) {
        this.emf = emf;
    }
    public MovimentoJpaController() {
        this.emf = Persistence.createEntityManagerFactory("GerenciadorAlmoxarifadoPU");
    }
    private EntityManagerFactory emf = null;

    public EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    public void create(Movimento movimento) {
        if (movimento.getEstoqueList() == null) {
            movimento.setEstoqueList(new ArrayList<Estoque>());
        }
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Usuario idTblUsuario = movimento.getIdTblUsuario();
            if (idTblUsuario != null) {
                idTblUsuario = em.getReference(idTblUsuario.getClass(), idTblUsuario.getId());
                movimento.setIdTblUsuario(idTblUsuario);
            }
            Documento idTblDocumento = movimento.getIdTblDocumento();
            if (idTblDocumento != null) {
                idTblDocumento = em.getReference(idTblDocumento.getClass(), idTblDocumento.getId());
                movimento.setIdTblDocumento(idTblDocumento);
            }
            List<Estoque> attachedEstoqueList = new ArrayList<Estoque>();
            for (Estoque estoqueListEstoqueToAttach : movimento.getEstoqueList()) {
                estoqueListEstoqueToAttach = em.getReference(estoqueListEstoqueToAttach.getClass(), estoqueListEstoqueToAttach.getId());
                attachedEstoqueList.add(estoqueListEstoqueToAttach);
            }
            movimento.setEstoqueList(attachedEstoqueList);
            em.persist(movimento);
            if (idTblUsuario != null) {
                idTblUsuario.getMovimentoList().add(movimento);
                idTblUsuario = em.merge(idTblUsuario);
            }
            if (idTblDocumento != null) {
                idTblDocumento.getMovimentoList().add(movimento);
                idTblDocumento = em.merge(idTblDocumento);
            }
            for (Estoque estoqueListEstoque : movimento.getEstoqueList()) {
                Movimento oldIdTblMovimentoOfEstoqueListEstoque = estoqueListEstoque.getIdTblMovimento();
                estoqueListEstoque.setIdTblMovimento(movimento);
                estoqueListEstoque = em.merge(estoqueListEstoque);
                if (oldIdTblMovimentoOfEstoqueListEstoque != null) {
                    oldIdTblMovimentoOfEstoqueListEstoque.getEstoqueList().remove(estoqueListEstoque);
                    oldIdTblMovimentoOfEstoqueListEstoque = em.merge(oldIdTblMovimentoOfEstoqueListEstoque);
                }
            }
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void edit(Movimento movimento) throws IllegalOrphanException, NonexistentEntityException, Exception {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Movimento persistentMovimento = em.find(Movimento.class, movimento.getId());
            Usuario idTblUsuarioOld = persistentMovimento.getIdTblUsuario();
            Usuario idTblUsuarioNew = movimento.getIdTblUsuario();
            Documento idTblDocumentoOld = persistentMovimento.getIdTblDocumento();
            Documento idTblDocumentoNew = movimento.getIdTblDocumento();
            List<Estoque> estoqueListOld = persistentMovimento.getEstoqueList();
            List<Estoque> estoqueListNew = movimento.getEstoqueList();
            List<String> illegalOrphanMessages = null;
            for (Estoque estoqueListOldEstoque : estoqueListOld) {
                if (!estoqueListNew.contains(estoqueListOldEstoque)) {
                    if (illegalOrphanMessages == null) {
                        illegalOrphanMessages = new ArrayList<String>();
                    }
                    illegalOrphanMessages.add("You must retain Estoque " + estoqueListOldEstoque + " since its idTblMovimento field is not nullable.");
                }
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            if (idTblUsuarioNew != null) {
                idTblUsuarioNew = em.getReference(idTblUsuarioNew.getClass(), idTblUsuarioNew.getId());
                movimento.setIdTblUsuario(idTblUsuarioNew);
            }
            if (idTblDocumentoNew != null) {
                idTblDocumentoNew = em.getReference(idTblDocumentoNew.getClass(), idTblDocumentoNew.getId());
                movimento.setIdTblDocumento(idTblDocumentoNew);
            }
            List<Estoque> attachedEstoqueListNew = new ArrayList<Estoque>();
            for (Estoque estoqueListNewEstoqueToAttach : estoqueListNew) {
                estoqueListNewEstoqueToAttach = em.getReference(estoqueListNewEstoqueToAttach.getClass(), estoqueListNewEstoqueToAttach.getId());
                attachedEstoqueListNew.add(estoqueListNewEstoqueToAttach);
            }
            estoqueListNew = attachedEstoqueListNew;
            movimento.setEstoqueList(estoqueListNew);
            movimento = em.merge(movimento);
            if (idTblUsuarioOld != null && !idTblUsuarioOld.equals(idTblUsuarioNew)) {
                idTblUsuarioOld.getMovimentoList().remove(movimento);
                idTblUsuarioOld = em.merge(idTblUsuarioOld);
            }
            if (idTblUsuarioNew != null && !idTblUsuarioNew.equals(idTblUsuarioOld)) {
                idTblUsuarioNew.getMovimentoList().add(movimento);
                idTblUsuarioNew = em.merge(idTblUsuarioNew);
            }
            if (idTblDocumentoOld != null && !idTblDocumentoOld.equals(idTblDocumentoNew)) {
                idTblDocumentoOld.getMovimentoList().remove(movimento);
                idTblDocumentoOld = em.merge(idTblDocumentoOld);
            }
            if (idTblDocumentoNew != null && !idTblDocumentoNew.equals(idTblDocumentoOld)) {
                idTblDocumentoNew.getMovimentoList().add(movimento);
                idTblDocumentoNew = em.merge(idTblDocumentoNew);
            }
            for (Estoque estoqueListNewEstoque : estoqueListNew) {
                if (!estoqueListOld.contains(estoqueListNewEstoque)) {
                    Movimento oldIdTblMovimentoOfEstoqueListNewEstoque = estoqueListNewEstoque.getIdTblMovimento();
                    estoqueListNewEstoque.setIdTblMovimento(movimento);
                    estoqueListNewEstoque = em.merge(estoqueListNewEstoque);
                    if (oldIdTblMovimentoOfEstoqueListNewEstoque != null && !oldIdTblMovimentoOfEstoqueListNewEstoque.equals(movimento)) {
                        oldIdTblMovimentoOfEstoqueListNewEstoque.getEstoqueList().remove(estoqueListNewEstoque);
                        oldIdTblMovimentoOfEstoqueListNewEstoque = em.merge(oldIdTblMovimentoOfEstoqueListNewEstoque);
                    }
                }
            }
            em.getTransaction().commit();
        } catch (Exception ex) {
            String msg = ex.getLocalizedMessage();
            if (msg == null || msg.length() == 0) {
                Integer id = movimento.getId();
                if (findMovimento(id) == null) {
                    throw new NonexistentEntityException("The movimento with id " + id + " no longer exists.");
                }
            }
            throw ex;
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public void destroy(Integer id) throws IllegalOrphanException, NonexistentEntityException {
        EntityManager em = null;
        try {
            em = getEntityManager();
            em.getTransaction().begin();
            Movimento movimento;
            try {
                movimento = em.getReference(Movimento.class, id);
                movimento.getId();
            } catch (EntityNotFoundException enfe) {
                throw new NonexistentEntityException("The movimento with id " + id + " no longer exists.", enfe);
            }
            List<String> illegalOrphanMessages = null;
            List<Estoque> estoqueListOrphanCheck = movimento.getEstoqueList();
            for (Estoque estoqueListOrphanCheckEstoque : estoqueListOrphanCheck) {
                if (illegalOrphanMessages == null) {
                    illegalOrphanMessages = new ArrayList<String>();
                }
                illegalOrphanMessages.add("This Movimento (" + movimento + ") cannot be destroyed since the Estoque " + estoqueListOrphanCheckEstoque + " in its estoqueList field has a non-nullable idTblMovimento field.");
            }
            if (illegalOrphanMessages != null) {
                throw new IllegalOrphanException(illegalOrphanMessages);
            }
            Usuario idTblUsuario = movimento.getIdTblUsuario();
            if (idTblUsuario != null) {
                idTblUsuario.getMovimentoList().remove(movimento);
                idTblUsuario = em.merge(idTblUsuario);
            }
            Documento idTblDocumento = movimento.getIdTblDocumento();
            if (idTblDocumento != null) {
                idTblDocumento.getMovimentoList().remove(movimento);
                idTblDocumento = em.merge(idTblDocumento);
            }
            em.remove(movimento);
            em.getTransaction().commit();
        } finally {
            if (em != null) {
                em.close();
            }
        }
    }

    public List<Movimento> findMovimentoEntities() {
        return findMovimentoEntities(true, -1, -1);
    }

    public List<Movimento> findMovimentoEntities(int maxResults, int firstResult) {
        return findMovimentoEntities(false, maxResults, firstResult);
    }

    private List<Movimento> findMovimentoEntities(boolean all, int maxResults, int firstResult) {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            cq.select(cq.from(Movimento.class));
            Query q = em.createQuery(cq);
            if (!all) {
                q.setMaxResults(maxResults);
                q.setFirstResult(firstResult);
            }
            return q.getResultList();
        } finally {
            em.close();
        }
    }

    public Movimento findMovimento(Integer id) {
        EntityManager em = getEntityManager();
        try {
            return em.find(Movimento.class, id);
        } finally {
            em.close();
        }
    }

    public int getMovimentoCount() {
        EntityManager em = getEntityManager();
        try {
            CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
            Root<Movimento> rt = cq.from(Movimento.class);
            cq.select(em.getCriteriaBuilder().count(rt));
            Query q = em.createQuery(cq);
            return ((Long) q.getSingleResult()).intValue();
        } finally {
            em.close();
        }
    }
    
}
